package com.woniu.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.commons.exception.YogaException;
import com.woniu.commons.model.Result;
import com.woniu.commons.util.JwtUtil;
import com.woniu.commons.util.RedisUtil;
import com.woniu.model.dto.UserDto;
import com.woniu.model.entity.YUser;
import com.woniu.model.form.*;
import com.woniu.model.param.*;
import com.woniu.service.YUserService;
import com.woniu.util.FileUtil;
import com.woniu.util.OSSUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 胡歌
 * @since 2024年05月22日
 */
@RestController
@RequestMapping("/yUser")
@Api(tags = "用户操作信息的一些接口")
public class YUserController {

    @Resource
    private YUserService userService;
    @Resource
    private RedisUtil redisUtil;

    @Resource
    private OSSUtil ossUtil;


    /**
     * 发送注册验证码的接口
     * @param mobile
     * @return
     * @throws Exception
     */
    @GetMapping("/sendRegisterCode")
    @ApiOperation(value = "发送注册验证码的接口")
    public Result sendRegisterCode(@RequestParam("mobile") String mobile) throws Exception {
        userService.sendRegisterCode(mobile);
        return Result.newInstance(null).setMsg("发送注册验证码成功").setCode(200);
    }

    /**
     *用户的手机号注册
     *   需要带的参数为注册时发送的验证码 code;
     *      userName;
     *      userNickname;
     *      userPhone;
     *      userEmail;
     *      userPass;
     *     身份证 idCard;
     * @param
     * @return
     */
    @PostMapping("/codeRegister")
    @ApiOperation(value = "用户点击注册的接口")
    public Result registerByCode(@RequestBody CodeRegisterForm form) throws  Exception{
        CodeRegisterParam param = BeanUtil.toBean(form, CodeRegisterParam.class);
        userService.CodeRegister(param);
        return Result.newInstance(null).setCode(200).setMsg("注册成功");
    }



    /**
     *用户的账号密码登录
     * @param
     * @return
     */
    @PostMapping("/userLogin")
    @ApiOperation(value = "用户账号密码登录的接口")
    public Result userlogin(@RequestBody UserInfoLoginForm form, HttpServletResponse response) throws    Exception{

        UserDto dto = userService.userlogin(BeanUtil.toBean(form, UserInfoLoginParam.class));

        Map<String, Object> map = BeanUtil.beanToMap(dto);
        HashMap<String, Object> acccessBoby = new HashMap<>();
        String random = new Snowflake(1, 1).nextIdStr();//雪花算法，生成一个随机值，确保不同的短token不一致
        acccessBoby.put("random",random);

        String accessToken = JwtUtil.createToken(acccessBoby, 15);//生成一个短token
        String refreshToken = JwtUtil.createToken(map, 3*24*60);//生成一个长token
        //将长token保存到redis
        redisUtil.set(accessToken,refreshToken,3*24*60*60);
        //响应token给前端
        response.setHeader("token", accessToken);
        response.setHeader("Access-Control-Expose-Headers", "token");
        return Result.newInstance(UserDto.class).setData(dto).setMsg("登录成功");
    }


    /**
     *用户修改个人头像  传入图片地址转换为字符串
     * @param
     * @return
     */
    @PostMapping("/updateImage")
    @ApiOperation("用户修改个人头像")
    public Result updateImage(UpdateUserImageForm form, @RequestHeader String token)throws Exception{
        String refreshToken = redisUtil.get(token);
        Integer coachId = Integer.parseInt(JwtUtil.parseToken(refreshToken).get("userId").toString());
        if (!FileUtil.isImageFile(form.getImage().getInputStream())){
            throw  new YogaException(9999,"文件类型错误");
        }
        String oldName = form.getImage().getOriginalFilename();
        String suffix = oldName.substring(oldName.lastIndexOf("."));
        String name = UUID.randomUUID().toString();
        String filePath = ossUtil.uploadFile(form.getImage().getInputStream(), name + suffix, "woniupengyuyan");
        UpdateUserImageParam param = BeanUtil.toBean(form, UpdateUserImageParam.class);
        param.setUserId(coachId);
        param.setImage(filePath);
        userService.updateImage(param);
        return Result.getResult().setMsg("修改个人头像成功");
    }



    /**
     *用户修改个人昵称  传入要修改的用户的ID  和修改的昵称
     * @param
     * @return
     */
    @Transactional
    @PostMapping("/UpdateNickName")
    @ApiOperation("用户修改个人昵称")
    public  Result UpdateNickName(@RequestBody UpdateNickNameForm form, @RequestHeader String token)throws Exception{
        String refreshToken = redisUtil.get(token);
        Integer userId = Integer.parseInt(JwtUtil.parseToken(refreshToken).get("userId").toString());
        UpdateNickNameParam param = BeanUtil.toBean(form, UpdateNickNameParam.class);
        param.setUserId(userId);
        YUser user = userService.UpdateNickName(param);
        return Result.newInstance(YUser.class).setData(user).setMsg("修改成功");
    }



    /**
     * 根据id查找用户信息
     * @param id
     * @return
     */
    @GetMapping("/byId/{id}")
    @ApiOperation("根据id查找用户信息")
    public Result<UserDto> byId(@PathVariable("id") Integer id){
        YUser user = userService.getById(id);
        return Result.newInstance(UserDto.class).setData(BeanUtil.toBean(user,UserDto.class));
    }

    /**
     * 用户修改密码  修改密码需要先传入之前的密码，然后在修改密码   新旧密码不能是重复的
     * @param
     * @return
     */
    @Transactional
    @GetMapping("/UpdateUserPassword")
    @ApiOperation("修改密码")
    public  Result UpdateUserPassword(String userPass,@RequestHeader String token)throws Exception{
        String refreshToken = redisUtil.get(token);
        Integer userId = Integer.parseInt(JwtUtil.parseToken(refreshToken).get("userId").toString());
        UpdateUserPasswordParam param = new UpdateUserPasswordParam();
        param.setUserId(userId);
        param.setUserPass(userPass);
        userService.UpdateUserPassword(param);
        return Result.getResult().setMsg("修改密码成功");
    }
    /**
     *用户发送修改手机号验证码
     *
     * @param
     * @return
     */
    @GetMapping("/UpdateUserPhone")
    @ApiOperation(value = "发送修改手机号验证码的接口")
    public Result UpdateUserPhone(@RequestParam("mobile") String mobile) throws Exception {
        userService.UpdateUserPhone(mobile);
        return Result.newInstance(null).setMsg("发送修改手机号验证码成功").setCode(200);
    }

    /**
     *用户的手机号修改
     * 需要传的值  老的手机号 发送的验证码code  在传入新的手机号
     * @param
     * @return
     */
    @PostMapping("/codeUpdate")
    @ApiOperation(value = "用户修改手机号的接口")
    public Result codeUpdate(@RequestBody CodeUpdateForm form) throws  Exception{
        userService.codeUpdate(BeanUtil.toBean(form, CodeUpdateParam.class));
        return Result.newInstance(null).setCode(200).setMsg("修改手机号成功");
    }


    /**
     *判断用户身份证是否合法
     *
     * @param
     * @return
     */
    @GetMapping("/inspectIdCard")
    @ApiOperation(value = "判断用户身份证是否合法")
    public Result inspectIdCard(String IdCard) throws Exception {
        boolean b = userService.inspectIdCard(IdCard);
        if (b==true) return Result.getResult().setMsg("身份证验证成功");

        return Result.getResult().setMsg("身份证不合法");
    }

    /**
     * 传入用户身份证号码 和姓名
     * @param form
     * @return
     */
    @ApiOperation("用户实名认证")
    @PostMapping("/realNameAuthentication")
    public Result<String> userRealNameAuthentication(@RequestBody RealNameAuthenticationForm form){
        String str = userService.userRealNameAuthentication(form);
        return Result.newInstance(String.class).setMsg(str);
    }

    /**
     * 分页查询所有用户
     * @param form
     * @return
     * @throws Exception
     */
    @GetMapping("/pageAllUser")
    @ApiOperation("分页查询所有用户")
    public Result pageAllUser( PageAllForm form) throws YogaException {
        Page<YUser> page = userService.pageAllUser(BeanUtil.toBean(form, PageAllParam.class));
        return Result.newPageInstance(YUser.class).setMsg("查询成功").setData(page).setCode(200);
    }

    /**
     * 分页查询所有学员
     * @param form
     * @return
     * @throws Exception
     */
    @GetMapping("/pageAllStudent")
    @ApiOperation("分页查询所有学员")
    public Result<Page<YUser>> pageAllStudent( PageAllStudentForm form,@RequestHeader String token) throws YogaException {
        String refreshToken = redisUtil.get(token);
        Integer coachId = Integer.parseInt(JwtUtil.parseToken(refreshToken).get("id").toString());
        form.setCoachId(coachId);
        Page<YUser> page = userService.pageAllStudent(form);
        return Result.newPageInstance(YUser.class).setMsg("查询成功").setData(page).setCode(200);
    }

    /**
     * 分页查询所有学员
     * @param form
     * @return
     * @throws Exception
     */
    @GetMapping("/pageAllPersonalStudent")
    @ApiOperation("分页查询所有学员")
    public Result<Page<YUser>> pageAllPersonalStudent( PageAllStudentForm form,@RequestHeader String token) throws YogaException {
        String refreshToken = redisUtil.get(token);
        Integer coachId = Integer.parseInt(JwtUtil.parseToken(refreshToken).get("id").toString());
        form.setCoachId(coachId);
        Page<YUser> page = userService.pageAllPersonalStudent(form);
        return Result.newPageInstance(YUser.class).setMsg("查询成功").setData(page).setCode(200);
    }

    /**
     * 根据id查找用户信息
     * @param userId
     * @return
     */
    @GetMapping("/loadUsersByIds")
    @ApiOperation("根据id查找用户信息")
    public Result<YUser> loadUsersByIds(Integer userId){
        YUser users = userService.loadUsersByIds(userId);
        return Result.newInstance(YUser.class).setData(users);
    }

}

